package com.zxicet.pdf.controller;

import com.zxicet.common.core.base.Result;
import com.zxicet.common.core.exception.CustomException;
import com.zxicet.pdf.config.FileConfigurationProperties;
import com.zxicet.pdf.model.FileAttribute;
import com.zxicet.pdf.model.FileType;
import com.zxicet.pdf.service.OfficeToPdfService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Slf4j
@RequestMapping("/demo")
@RestController
@RequiredArgsConstructor
public class DemoController {

    private final OfficeToPdfService officeToPdfService;
    private final FileConfigurationProperties fileConfigurationProperties;

    @PostMapping("/upload")
    public Result upload(@RequestBody MultipartFile file, Model model){

        String fileName = file.getOriginalFilename();

        String filePath = fileConfigurationProperties.getStoreWay() + fileName;

        // 存储到本地路径
        FileOutputStream fileOutputStream = null;
        File tempFile = new File(fileConfigurationProperties.getStoreWay());
        try {
            if (!tempFile.exists()) {
                // 创建目录
                tempFile.mkdirs();
            }
            fileOutputStream = new FileOutputStream(filePath);
            IOUtils.copy(file.getInputStream(), fileOutputStream);
        } catch (Exception e) {
            throw new CustomException("文件上传报错了", e);
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
            }
        }
        return Result.ok(toPdf(model, fileName));
    }

    @GetMapping("/handle/{fileName}")
    public Result handle(@PathVariable("fileName") String fileName, Model model){
        return Result.ok(toPdf(model, fileName));
    }

    private Integer toPdf(Model model, String fileName) {
        String name = fileName.substring(0, fileName.lastIndexOf("."));
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        String pdfName = name + ".pdf";

        String filePath = fileConfigurationProperties.getStoreWay() + fileName;
        String outFilePath = fileConfigurationProperties.getStoreWay() + "123/" + pdfName;

        FileAttribute fileAttribute = new FileAttribute();
        fileAttribute.setType(FileType.typeFromFileName(fileName));
        fileAttribute.setSuffix(suffix);
        fileAttribute.setName(fileName);
        fileAttribute.setCompressFile(false);
        fileAttribute.setCompressFileKey(null);
        fileAttribute.setFilePassword(null);
        fileAttribute.setUsePasswordCache(false);
        fileAttribute.setTifPreviewType(null);
        fileAttribute.setSkipDownLoad(false);
        fileAttribute.setForceUpdatedCache(false);
        fileAttribute.setCacheName(pdfName);
        fileAttribute.setOutFilePath(outFilePath);
        fileAttribute.setOriginFilePath(filePath);
        fileAttribute.setCacheListName(name + ".ListName");
        fileAttribute.setHtmlView(false);
        fileAttribute.setKkProxyAuthorization(null);

        model.addAttribute("file", fileAttribute);
        long begin = System.currentTimeMillis();
        log.debug("转换开始");
        try {
            officeToPdfService.openOfficeToPDF(filePath, outFilePath, fileAttribute);
        } catch (Exception e) {
            log.debug("转换报错了：\n" + e);
        }
        long end = System.currentTimeMillis();
        log.debug("转换结束【{}】", end - begin);
        return Math.toIntExact(end - begin);
    }


    @GetMapping("/preview/{fileName}")
    public void preview(HttpServletResponse response, @PathVariable("fileName") String fileName) {

        String outFilePath = fileConfigurationProperties.getStoreWay() + "123/" + fileName;
        File file = new File(outFilePath);
        if (!file.exists()) {
            throw new CustomException("文件不存在");
        }
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            response.setContentType(Files.probeContentType(Paths.get(fileName)));
            response.setHeader("Access-Control-Allow-Origin", "*");    // 跨域，释放所有
            response.setContentLength((int) file.length());
            InputStream inputStream = Files.newInputStream(file.toPath());
            // 循环取出流中的数据
            byte[] b = new byte[1024];
            int len;
            while ((len = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("预览报错了", e);
        } finally {
            try {
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (Exception e) {
                throw new RuntimeException("预览关流失败", e);
            }
        }
    }

    @GetMapping("/download/{fileName}")
    public void download(HttpServletResponse response, @PathVariable("fileName") String fileName) {

        String outFilePath = fileConfigurationProperties.getStoreWay() + "123/" + fileName;
        File file = new File(outFilePath);
        if (!file.exists()) {
            throw new CustomException("文件不存在");
        }
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            response.reset();
            response.setContentType(Files.probeContentType(Paths.get(fileName)));
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            // 不设置Content-Disposition,前端浏览器就是在线预览，如果配置了这个，浏览器就是下载文件
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setHeader("Access-Control-Allow-Origin", "*");    // 跨域，释放所有
            response.setContentLength((int) file.length());

            InputStream inputStream = Files.newInputStream(file.toPath());
            // 循环取出流中的数据
            byte[] b = new byte[1024];
            int len;
            while ((len = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("下载报错了", e);
        } finally {
            try {
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (Exception e) {
                throw new RuntimeException("下载关流失败", e);
            }
        }
    }

    @GetMapping("/list")
    public Result<List<String>> list() {
        log.debug("list列表查询");
        String filePath = fileConfigurationProperties.getStoreWay() + "123/";
        File file = new File(filePath);
        String[] fileNameList = file.list();
        if (fileNameList != null) {
            return Result.ok(Arrays.asList(fileNameList));
        }
        return Result.ok();
    }





}
